Add a generic callback content provider
authorMatthias Clasen <mclasen@redhat.com>
Tue, 31 Dec 2019 16:48:22 +0000 (11:48 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 8 Jan 2020 23:48:19 +0000 (18:48 -0500)
This one is convenient to use in cases where a
drag is just serving an existing GType which
is covered by content serializers.

gdk/gdkcontentproviderimpl.c
gdk/gdkcontentproviderimpl.h

index e7b70c28ab0d35b80c2621f1234c6c9d93ea6d1a..5278cd2c86b825fd47415b6dc56425f21e51bc8a 100644 (file)
@@ -280,3 +280,90 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
   
   return GDK_CONTENT_PROVIDER (content);
 }
+
+#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK            (gdk_content_provider_callback_get_type ())
+#define GDK_CONTENT_PROVIDER_CALLBACK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK, GdkContentProviderCallback))
+
+typedef struct _GdkContentProviderCallback GdkContentProviderCallback;
+typedef struct _GdkContentProviderCallbackClass GdkContentProviderCallbackClass;
+
+struct _GdkContentProviderCallback
+{
+  GdkContentProvider parent;
+
+  GType type;
+  GdkContentProviderGetValueFunc func;
+  gpointer data;
+};
+
+struct _GdkContentProviderCallbackClass
+{
+  GdkContentProviderClass parent_class;
+};
+
+GType gdk_content_provider_callback_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE (GdkContentProviderCallback, gdk_content_provider_callback, GDK_TYPE_CONTENT_PROVIDER)
+
+static GdkContentFormats *
+gdk_content_provider_callback_ref_formats (GdkContentProvider *provider)
+{
+  GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
+
+  return gdk_content_formats_new_for_gtype (callback->type);
+}
+
+static gboolean
+gdk_content_provider_callback_get_value (GdkContentProvider  *provider,
+                                         GValue              *value,
+                                         GError             **error)
+{
+  GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
+
+  if (G_VALUE_HOLDS (value, callback->type) && callback->func != NULL)
+    {
+      callback->func (value, callback->data);
+      return TRUE;
+    }
+
+  return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_callback_parent_class)->get_value (provider, value, error);
+}
+
+static void
+gdk_content_provider_callback_class_init (GdkContentProviderCallbackClass *class)
+{
+  GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
+
+  provider_class->ref_formats = gdk_content_provider_callback_ref_formats;
+  provider_class->get_value = gdk_content_provider_callback_get_value;
+}
+
+static void
+gdk_content_provider_callback_init (GdkContentProviderCallback *content)
+{
+}
+
+/**
+ * gdk_content_provider_new_for_callback:
+ * @type: the type that the callback provides
+ * @func: callback to populate a #GValue
+ * @data: data that gets passed to @func
+ *
+ * Create a content provider that provides data that is provided via a callback.
+ *
+ * Returns: a new #GdkContentProvider
+ **/
+GdkContentProvider *
+gdk_content_provider_new_with_callback (GType                          type,
+                                        GdkContentProviderGetValueFunc func,
+                                        gpointer                       data)
+{
+  GdkContentProviderCallback *content;
+
+  content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK, NULL);
+  content->type = type;
+  content->func = func;
+  content->data = data;
+  
+  return GDK_CONTENT_PROVIDER (content);
+}
index 1c41360243341c5debe5332776b9c553cc444622..b98d02bdefe3a13e8b8efd8720b14e6e26f6b8de 100644 (file)
@@ -35,7 +35,13 @@ GDK_AVAILABLE_IN_ALL
 GdkContentProvider *    gdk_content_provider_new_for_bytes              (const char             *mime_type,
                                                                          GBytes                 *bytes);
 
+typedef void (*GdkContentProviderGetValueFunc) (GValue   *value,
+                                                gpointer  data);
 
+GDK_AVAILABLE_IN_ALL
+GdkContentProvider *    gdk_content_provider_new_with_callback          (GType                          type,
+                                                                         GdkContentProviderGetValueFunc func,
+                                                                         gpointer                       data);                                                                          
 G_END_DECLS
 
 #endif /* __GDK_CONTENT_PROVIDER_IMPL_H__ */